package com.qyl.framework.client.decoder;

import java.util.List;

import com.qyl.framework.base.Message;
import com.qyl.framework.base.protocol.ResponseProto;
import com.qyl.framework.utils.ParamsUtils;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

public class ResponseProtoDecoder extends ByteToMessageDecoder{

	@Override
	@SuppressWarnings("unchecked")
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		ResponseProto proto = new ResponseProto();
		
		long responseId = in.readLong();
		proto.setReponseId(responseId);
		
		int classNameLen = in.readByte();
		byte[] classNameByte = new byte[classNameLen];
		in.readBytes(classNameByte);
		
		String className = new String(classNameByte);
		Class<?> classz = Class.forName(className);
		if (classz.isAssignableFrom(Message.class)) {
			Message message = ParamsUtils.fromBuffer(in, (Class<Message>)classz);
			proto.setResponse(message);
		} else if (isPrimitiveOrString(classz)) {
			Object object = ParamsUtils.fromBufferForSimpleType(in, classz);
			proto.setResponse(object);
		}
		out.add(proto);
	}

	private boolean isPrimitiveOrString(Class<?> classz) {
		if (classz == Byte.class || classz == byte.class){
			return true;
		} else if (classz == Short.class || classz == short.class){
			return true;
		} else if (classz == Long.class || classz == Long.class){
			return true;
		} else if (classz == Boolean.class || classz == boolean.class){
			return true;
		} else if (classz == Float.class || classz == float.class){
			return true;
		} else if (classz == Double.class || classz == double.class){
			return true;
		} else if (classz == Character.class || classz == char.class){
			return true;
		} else if (classz == String.class){
			return true;
		}
		return false;
	}
}
